
import com.github.junrar.Archive;
import com.github.junrar.rarfile.FileHeader;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;

import java.io.*;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

/**
 * @author zhangdi
 * @version 1.0
 * @date 2022.10.9 17:28
 */
public class FileUnZipRar {
    private final static String SRC_PATH = "E:\\ppppppp\\livp";
    private final static String TO_FOLDER_PATH = "E:\\ppppppp\\livp_convert";

    public static void main(String[] args) {
        List<File> allFileList = getAllFileList(SRC_PATH);
        zipRarToFile(allFileList);
    }


    private static void zipRarToFile(List<File> allFileList) {
        if (CollectionUtils.isEmpty(allFileList)) {
            return;
        }

        for (File file : allFileList) {
            zipRarToFile(file);
        }


    }

    /**
     * 解压
     *
     * @param pushFile
     */
    private static void zipRarToFile(File pushFile) {

        String fileName = pushFile.getName();

        int pos = fileName.lastIndexOf(".");
        String extName = fileName.substring(pos + 1).toLowerCase();
        File descFile = new File(TO_FOLDER_PATH);
        if (!descFile.exists()) {
            descFile.mkdirs();
        }

        if (extName.equals("zip") || extName.equals("livp")) {
            //开始解压zip
            FileUnZipRar.unZipFiles(pushFile);
        } else if (extName.equals("rar")) {
            //开始解压rar
//            FileUnZipRar.unRarFile(pushFile.getAbsolutePath());
        }else {
            System.out.println("无法解压：" + pushFile.getAbsolutePath());
        }

    }

    /**
     * 检查是否有index.html
     *
     * @param strPath
     * @return
     */
    public static List<File> getAllFileList(String strPath) {
        List<File> filelist = new ArrayList<File>();
        getFileList(filelist, strPath); // 该文件目录下文件全部放入数组

        return filelist;
    }

    /**
     * 获取所有文件
     *
     * @param strPath
     * @return
     */
    public static List<File> getFileList(List<File> filelist, String strPath) {
        File dir = new File(strPath);
        File[] files = dir.listFiles(); // 该文件目录下文件全部放入数组

        if (ArrayUtils.isEmpty(files)) {
            return null;
        }

        for (int i = 0; i < files.length; i++) {
            if (files[i].isDirectory()) { // 判断是文件还是文件夹
                getFileList(filelist, files[i].getAbsolutePath()); // 获取文件绝对路径
            } else {
                filelist.add(files[i]);
                continue;
            }
        }

        return filelist;
    }

    /**
     * 解压文件到指定目录
     *
     * @param zipFile
     * @author isea533
     */
    @SuppressWarnings("rawtypes")
    public static void unZipFiles(File zipFile) {

        InputStream in = null;
        OutputStream out = null;

        try {

            ZipFile zip = new ZipFile(zipFile);
            for (Enumeration entries = zip.getEntries(); entries.hasMoreElements(); ) {
                ZipEntry entry = (ZipEntry) entries.nextElement();

                String outPath = TO_FOLDER_PATH + "\\" + entry.getName();
                System.out.println(outPath);

                in = zip.getInputStream(entry);
                out = new FileOutputStream(outPath);
                byte[] buf1 = new byte[1024];
                int len;
                while ((len = in.read(buf1)) > 0) {
                    out.write(buf1, 0, len);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 根据原始rar路径，解压到指定文件夹下.
     *
     * @param srcRarPath 原始rar路径
     */
    public static void unRarFile(String srcRarPath) {
        if (!srcRarPath.toLowerCase().endsWith(".rar")) {
            System.out.println("非rar文件！");
            return;
        }

        Archive a = null;
        try {
            a = new Archive(new File(srcRarPath));
            if (a == null) {
                return;
            }

            a.getMainHeader().print(); // 打印文件信息.
            FileHeader fh = a.nextFileHeader();
            while (fh != null) {
                if (fh.isDirectory()) { // 文件夹
                    File fol = new File(TO_FOLDER_PATH + File.separator + fh.getFileNameString());
                    fol.mkdirs();
                } else { // 文件
                    File out = new File(TO_FOLDER_PATH + File.separator + fh.getFileNameString().trim());
                    try {// 之所以这么写try，是因为万一这里面有了异常，不影响继续解压.
                        if (!out.exists()) {
                            if (!out.getParentFile().exists()) {// 相对路径可能多级，可能需要创建父目录.
                                out.getParentFile().mkdirs();
                            }
                            out.createNewFile();
                        }
                        FileOutputStream os = new FileOutputStream(out);
                        a.extractFile(fh, os);
                        os.close();
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
                fh = a.nextFileHeader();
            }
            a.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
